package com.johnzer.frame.utils;

import android.content.Context;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

public class MD5Filter {
	
	static char hexdigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
	// 传入文件获取文件的MD5值
	public static String getMd5ByFile(File file, Context con) {
		String value = null;
		FileInputStream in = null;
		try {
			in = new FileInputStream(file);
			MappedByteBuffer byteBuffer = in.getChannel().map(
					FileChannel.MapMode.READ_ONLY, 0, file.length());
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			md5.update(byteBuffer);
			BigInteger bi = new BigInteger(1, md5.digest());
			value = bi.toString(16);
		} catch (FileNotFoundException e) {
			//wyd  注掉  这种信息不能给用户看到
			//Toast.makeText(con, "未找到此文件", Toast.LENGTH_SHORT).show();
			e.printStackTrace();
		} catch (IOException e) {
			//Toast.makeText(con, "IO异常", Toast.LENGTH_SHORT).show();
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			//Toast.makeText(con, "没有此种算法", Toast.LENGTH_SHORT).show();
			e.printStackTrace();
		} finally {
			if (null != in) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return value;
	}

	// 传入文件路径
	public static String getMd5ByFileurl(String fileurl, Context con) {
		String value = null;
		File file = new File(fileurl);
//		value = getMd5ByFile(file, con);
		value =MD5(file);
		return value;
	}

	// 传入路径生成文件夹下所有文件的MD5并生成LIST
	public static List<String> getMd5ByFile(String Url, Context con) {
		List<String> valuses = new ArrayList<String>();
		File fileUrl = new File(Url);
		if (fileUrl.isDirectory()) {
			File[] fileList = fileUrl.listFiles();
			for (File file : fileList) {
				String val = getMd5ByFile(file, con);
				valuses.add(val);
			}
		} else {
			String val = getMd5ByFile(fileUrl, con);
			valuses.add(val);
		}
		return valuses;
	}

	public static String MD5(File s) {
		FileInputStream fis = null;
		try {
			// 获得MD5摘要算法的 MessageDigest 对象
			MessageDigest mdInst = MessageDigest.getInstance("MD5");

			fis = new FileInputStream(s);
			byte[] buffer = new byte[2048];
			int length = -1;
			while ((length = fis.read(buffer)) != -1) {
				mdInst.update(buffer, 0, length);
			}
			byte[] b = mdInst.digest();
			fis.close();
			fis=null;
			return byteToHexString(b);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	private static String byteToHexString(byte[] tmp) {
	    String s;
	    // 用字节表示就是 16 个字节  
	    char str[] = new char[16 * 2];
	    // 每个字节用 16 进制表示的话，使用两个字符，   
	    // 所以表示成 16 进制需要 32 个字符  
	    int k = 0;
	    // 表示转换结果中对应的字符位置   
	    for (int i = 0; i < 16; i++) {
	    // 从第一个字节开始，对 MD5 的每一个字节    
	    // 转换成 16 进制字符的转换   
	    byte byte0 = tmp[i];
	    // 取第 i 个字节   
	    str[k++] = hexdigits[byte0 >>> 4 & 0xf];
	    // 取字节中高 4 位的数字转换,     
	    // >>> 为逻辑右移，将符号位一起右移   
	    str[k++] = hexdigits[byte0 & 0xf];
	    // 取字节中低 4 位的数字转换  
	    }   
	    s = new String(str);
	    // 换后的结果转换为字符串  
	    return s;
	    }
	public static String md5String(String string) {
	    byte[] hash;
	    try {
	        hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
	    } catch (NoSuchAlgorithmException e) {
	        throw new RuntimeException("Huh, MD5 should be supported?", e);
	    } catch (UnsupportedEncodingException e) {
	        throw new RuntimeException("Huh, UTF-8 should be supported?", e);
	    }

	    StringBuilder hex = new StringBuilder(hash.length * 2);
	    for (byte b : hash) {
	        if ((b & 0xFF) < 0x10) hex.append("0");
	        hex.append(Integer.toHexString(b & 0xFF));
	    }
	    return hex.toString();
	}
	// public static void main(String[] args) {
	// String root = Environment.getExternalStorageDirectory()
	// .getAbsolutePath();
	// String v = MD5Filter.getMd5ByFile(new File(root + "/test.txt"));
	// System.out.println(v.toUpperCase());
	// }
}
